#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>

#define COMMAND_SIZE 1024
#define FORMAT "[%s@%s %s]#"
char cwd[1024];

//定义的全局变量
#define MAXARGC 128
char* g_argv[MAXARGC];
int g_argc;

const char* GetUserName()//获得用户名函数
{
    const char* name = getenv("USER");
    return name == NULL? "None":name;
}

const char* GetHostName()//获得主机名
{
    const char* hostname = getenv("HOSTNAME");
    return hostname == NULL?"None":hostname;
}

const char* GetPwd()//获得路径
{
    char* pwd = getcwd(cwd,sizeof(cwd));
    return pwd == NULL?"None":pwd;
}

const char* GetHome()
{
    const char* home = getenv("HOME");
    return home == NULL?"":home;
}

std::string DirName(const char* pwd)
{
    std::string dir = pwd;
    if(dir == "/") return "/";
    auto pos = dir.rfind("/");
    if(pos == std::string::npos) return "BUG";
    return dir.substr(pos+1);
}

void MakeCommandline(char cmdline[],int size)//制作一个命令行
{
    //snprintf(cmdline,size,"[%s@%s %s]#",GetUserName(),GetHostName(),DirName(GetPwd()).c_str());
    snprintf(cmdline,size,"[%s@%s %s]#",GetUserName(),GetHostName(),GetPwd());
}

void PrintCommandPrompt()//打印命令行提示符
{
    char prompt[COMMAND_SIZE];
    MakeCommandline(prompt,sizeof(prompt));
    printf("%s",prompt);
    fflush(stdout);
}

bool GetCommandLine(char* out,int size)
{
    char *c = fgets(out,size,stdin);
    if(c==NULL) return false;
    out[strlen(out)-1]=0;//清理\n，因为输入完之后会按下一个回车键，会有换行，所以就要将其最后一个位置设置成0，不要让他换行
    if(strlen(out)==0) return false;
    return true;
}


bool CommandParse(char* commandline)
{
#define SEP " "
    g_argc=0;
    g_argv[g_argc++]=strtok(commandline,SEP);//吧第一个字符串截取出来了
    while(g_argv[g_argc++] = strtok(nullptr,SEP));
    g_argc--;
    return g_argc>0?true:false;
}

int Execute()
{
    pid_t id = fork();
    if(id==0)
    {
        //child
        execvp(g_argv[0],g_argv);
        exit(1);
    }
    //father
    pid_t rid = waitpid(id,nullptr,0);
    (void)rid;
    return 0;
}

bool CheckAndExcBuild()
{
    std::string cmd = g_argv[0];
    if(cmd == "cd")
    {
        if(g_argc=1)
        {
            std::string home = GetHome();
            if(home.empty()) return true;

            chdir(home.c_str());
        }
    
        else
        {
            std::string where =g_argv[1];
            if(where=="-")
            {}
            else if(where=="~")
            {}
            else
            {
                chdir(where.c_str());
            }
        }
    return true;
    }
    return false;
}



int main()
{
    while(true)
    {
         //1.输出命令行提示符号
         PrintCommandPrompt();
    
        //2.获取用户输入的命令
        char commandline[COMMAND_SIZE];
        if(!GetCommandLine(commandline,sizeof(commandline)))
            continue;
        //3.拆字符串
        if(!CommandParse(commandline))
            continue;

        //4.检测并且处理内建命令
        if(CheckAndExcBuild())
           continue;

        //4.执行命令
        Execute();

    }
}
